package org.luxor.commons.security.annotation;

import org.luxor.commons.security.config.WebSecurityProperties;
import org.luxor.commons.security.config.resource.OAuth2ResourceServerBeanDefinitionRegistrar;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.AdviceMode;
import org.springframework.context.annotation.Import;
import org.springframework.core.Ordered;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;

import java.lang.annotation.*;

/**
 * 启用 OAuth2资源提供方-通用安全策略
 *
 * @author Mr.Yan  @date: 2020/9/21
 */
@Documented
@Inherited
@EnableResourceServer
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableConfigurationProperties(WebSecurityProperties.class)
@Import(OAuth2ResourceServerBeanDefinitionRegistrar.class)
public @interface EnableOAuth2ResourceServer {

    /**
     * Indicate whether subclass-based (CGLIB) proxies are to be created ({@code true}) as
     * opposed to standard Java interface-based proxies ({@code false}). The default is
     * {@code false}. <strong>Applicable only if {@link #mode()} is set to
     * {@link AdviceMode#PROXY}</strong>.
     *
     * <p>
     * Note that setting this attribute to {@code true} will affect <em>all</em>
     * Spring-managed beans requiring proxying, not just those marked with the Security
     * annotations. For example, other beans marked with Spring's {@code @Transactional}
     * annotation will be upgraded to subclass proxying at the same time. This approach
     * has no negative impact in practice unless one is explicitly expecting one type of
     * proxy vs another, e.g. in tests.
     *
     * @return true if CGILIB proxies should be created instead of interface based
     * proxies, else false
     */
    boolean proxyTargetClass() default false;

    /**
     * Indicate how security advice should be applied. The default is
     * {@link AdviceMode#PROXY}.
     *
     * @return the {@link AdviceMode} to use
     * @see AdviceMode
     */
    AdviceMode mode() default AdviceMode.PROXY;

    /**
     * Indicate the ordering of the execution of the security advisor when multiple
     * advices are applied at a specific joinpoint. The default is
     * {@link Ordered#LOWEST_PRECEDENCE}.
     *
     * @return the order the security advisor should be applied
     */
    int order() default Ordered.LOWEST_PRECEDENCE;

}
